/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Scenery;

import Scenery.Equipment.Equipment;
import Scenery.Thing.Weapons.Weapon;
import Scenery.Thing.Weapons.Weapons.Axe;
import main.DumbMath;
import main.MouseInputListener;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.collision.CollisionResults;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import main.Events.Entity.EntityHitEvent;
import main.Main;
import main.Memory.Cooldown;

/**
 *
 * @author usuario
 * 
 */

public class BaseCharacter extends BaseSprite {

    protected final float naturalSpeedModifier = 0.15f;
    protected float speedModifier = 0.2f;
    private Integer readingSignId = null;
    protected CharacterControl control;
    protected Vector3f walkDir = new Vector3f();
    protected Cooldown pickCooldown;
    public boolean frozen = false; 
    public boolean adjustingFeet = false;
    private boolean movingBackwards = false;
    private Weapon rHandWeapon = null;
    
    
    public BaseCharacter() {
        masterNode.setLocalTranslation(new Vector3f(0, 10f, 0));
        masterNode.attachChild(model);
        control = new CharacterControl(new SphereCollisionShape(0.8f), .9f);
        control.setPhysicsLocation(model.getLocalTranslation());
        control.setFallSpeed(10f);
        masterNode.addControl(control);
        control.setPhysicsLocation(new Vector3f(0f, 10f, 0f));
    }
    
    public void attack() {
            // animation.stopAnimation("Step");
            animation.stopAnimation("ChestBounce");
            animation.stopAnimation("HeadBob");
            animation.stopAnimation("ChestTurn");
            animation.stopAnimation("HandBangle");
            animation.setAnimationParameter("Attack", rHandWeapon);
            animation.playAnimation("Attack");
    }
    
    public Vector3f getLookDir() {
        float [] angles = new float[3];
        headNode.getLocalRotation().toAngles(angles);
        float radius = 1;
        return new Vector3f(FastMath.cos(-angles[1]) * radius, radius, FastMath.sin(-angles[1]) * radius);
    }

    public void moveTowards(Vector3f v) {
        if(!isAttacking()) {
            if(!movingBackwards) {
                animation.playAnimation("Step");
                    animation.playAnimation("HeadBob");
                    animation.playAnimation("ChestBounce");
                    animation.playAnimation("ChestTurn");
            } else {
                animation.playAnimation("StepTurn");
            }
            animation.playAnimation("HandBangle");
        }
        //animation.playAnimation("Step");
        walkDir.addLocal(v);
    }

    
    
    public void equipWeapon(Weapon w) {
        this.rHandWeapon = w;
        this.rHandNode.attachChild(w.getMasterWeaponNode());
    }
    
    private void adjustMovingBackwards() {
       double dif = DumbMath.angleDif(bodyAngle, footAngle);
       if (dif > 100 || dif < -100) {
           movingBackwards = true; 
           speedModifier = naturalSpeedModifier*0.5f;
       } else {
           movingBackwards = false; 
           speedModifier = naturalSpeedModifier;
       }
    }

    // magic method
    public void setLookDirection(float cameraRotation, float mouseAngle) {
        headAngle = mouseAngle - cameraRotation;
        double dif = DumbMath.angleDif(DumbMath.getNodeAngle(headNode), bodyAngle);
        float oldBodyAngle = bodyAngle;
        int maxDif = 45;
        if(isMoving()) maxDif = 15;
        if (dif > maxDif) {
            bodyAngle -= 15f;
        } else if (dif < -maxDif) {
            bodyAngle += 15f;
        }
        dif = DumbMath.angleDif(bodyAngle, footAngle);
        if (!isMoving()) {
            if (dif > 25) {
                footAngle -= 5f;
                adjustingFeet = true;
            } else if (dif < -25) {
                footAngle += 5;
                adjustingFeet = true;
            } else 
                adjustingFeet = false;
            if (adjustingFeet == true) 
                animation.playAnimation("StepTurn");
        } else
            footAngle = DumbMath.getAngle(walkDir.x, walkDir.z);
        adjustMovingBackwards();
        DumbMath.turnTo(legNode, footAngle);
        DumbMath.turnTo(masterBodyNode, bodyAngle);
        DumbMath.turnToInvesrse(headNode, headAngle+180);
    }
    
    public boolean isAttacking() {
        return animation.isAnimationPlayng("Attack");
    }

    public void checkDeath() {
        if (control.getPhysicsLocation().y < -30) {
            control.setPhysicsLocation(new Vector3f(0f, 100f, 0f));
        }
    }
    
    public void checkContact(Ray r) {
        Node collidable = null;
        if(rHandWeapon instanceof Weapon) {
           collidable = Main.getHandler().mapControl.getMap().getRootMapNode();
        } else return;
        CollisionResults results = new CollisionResults();
        collidable.collideWith(r, results);
        if(results != null && results.size() > 0) {
            Main.getHandler().getEventHandler().callEvent(new EntityHitEvent(this, results.getClosestCollision().getGeometry()));
        }
    
    }
    
    public void pickUp(Geometry g) {
        if(!isMoving())  {
            //animation.setAnimationParameter("PickUp", g);
            //animation.playAnimation("PickUp");
        }
    }

    public void positionTick() {
        control.setWalkDirection(walkDir);
        if (!isMoving()) {
            animation.stopAnimation("Step");
            animation.stopAnimation("ChestBounce");
            animation.stopAnimation("HeadBob");
            animation.stopAnimation("ChestTurn");
            animation.stopAnimation("HandBangle");
        } else if(isMoving() && movingBackwards) {
            animation.stopAnimation("Step");
            animation.stopAnimation("ChestBounce");
            animation.stopAnimation("HeadBob");
            animation.stopAnimation("ChestTurn");
            //animation.stopAnimation("HandBangle");
        }
       animation.tick();
    }

    public boolean isMoving() {
        if (walkDir.x == 0 && walkDir.y == 0 && walkDir.z == 0) {
            return false;
        }
        return true;
    }

    public CharacterControl getControl() {
        return control;
    }

    public Vector3f getWalkDir() {
        return walkDir;
    }

    public void setWalkDir(Vector3f w) {
        walkDir = w;
    }

    public Integer getReadingSignId() {
        return this.readingSignId;
    }
    
    public void setReadingSignId(Integer i) {
        this.readingSignId = i;
    }
    
    
    
    public float getSpeedModifier() {
        return speedModifier;
    }
}
